package DataSource;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.nio.channels.SelectableChannel;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.omg.Messaging.SyncScopeHelper;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import Entity.HostTraffic;
//import Entity.DVData;
import Entity.Test;
import SQL.Config;
import SQL.DataCURD;

public class GetData {
	static String se = File.separator;
	public static void main(String[] args) throws IOException {  
      Runnable runnable = new Runnable() {  
          public void run() {  
      		//把远程文件拷贝到当前目录
//      		runShell(getFileShellPath);
      		try {
//				readMysql("application_attack_bak","f:/data/");
//      			readMysql(args[0],args[1]);
    			writeMysql("F:/data/application_attack_bak.txt","application_attack_bak");
//    			runShell("."+se+"rmfile.sh");
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}//读表并写入table_bak.txt的文件中
      		
          }  
      };  
      ScheduledExecutorService service = Executors  
              .newSingleThreadScheduledExecutor();  
      // 第二个参数为首次执行的延时时间，第三个参数为定时执行的间隔时间  
      service.scheduleAtFixedRate(runnable, 1, 120, TimeUnit.SECONDS); 
		
		//从数据库读取数据，写入指定路径（若无此文件会自动新建）
//		readMysql("application_attack","f:/data/");
//		readMysql("security_threat","f:/data/");
//		readMysql("security_event","f:/data/");
//		readMysql("odps_sas_threat_specific_analysis","f:/data/");
		
		//逐行读取文件数据
//		writeMysql("F:/data/application_attack_bak.txt","application_attack_bak");
//		writeMysql("F:/data/security_threat_bak.txt","security_threat_bak");
//		writeMysql("F:/data/security_event_bak.txt","security_event_bak");
//		writeMysql("F:/data/odps_sas_threat_specific_analysis_bak.txt","odps_sas_threat_specific_analysis_bak");
  } 
  
	  /** 
	   *  从数据库读取数据，
	   *  然后写入指定路径。
	   * @param filePath 目标文件 
	   * @param sql 从数据库中读取数据的sql（此sql读取的数据要求只能是指定的实体类） 
	 * @throws IOException 
	   */  
	public static void readMysql(String tableName,String filePath) throws IOException {
		String configPath = "src/SQL/id.properties";
		String idName = tableName+"_ID";
		Config config = new Config();
		Properties properties = config.getConfig(configPath);
		String idString = properties.getProperty(idName);
		
		DataCURD dataCURD = new DataCURD();
		dataCURD.initConfig();
		StringBuffer sb=new StringBuffer();
		String sql = " select * from "+tableName+" order by id DESC ";
		
		//获取数据最新id，命名规则为tableName+"_ID"，没有则新建，初始值为0
		if (null==idString) {
			OutputStream outputStream =  new FileOutputStream(configPath);
			properties.setProperty(idName, "0");
			properties.store(outputStream, configPath);
		}
		idString = properties.getProperty(idName);
		Long oldId = Long.valueOf(idString);
		System.out.println("oldId:"+oldId);
		Long newId = dataCURD.findId("select id from "+tableName+" ORDER BY id DESC LIMIT 1");
		System.out.println("newId:"+newId);
		if ((newId-oldId)>=0) {
			sql = sql +" LIMIT "+ (newId-oldId);
		} else {
			System.out.println("id增量异常：新id："+newId+"小于旧id："+oldId);
		}
		//把最新id更新到配置文件
		OutputStream outputStream =  new FileOutputStream(configPath);
		properties.setProperty(idName, newId.toString());
		properties.store(outputStream, configPath);

		//从数据库获取数据并直接转成json格式字符串，存放StringBuffer中
		sb = dataCURD.findSession(sql);
		System.out.println("数据提取成功。");

		//写数据到文件夹
		writeByFileOutputStream(sb,filePath+tableName+".txt");
		//将增量数据文件拷贝到外网数据采集设备上
//		runShell("."+se+"id.properties");
		
	}
	
	/** 
	 *  把数据写入指定路径
	 * @param filePath 目标文件 
	 * @param sb 需要写入的数据
	 */ 
	public static void writeByFileOutputStream(StringBuffer sb,String filePath) {  
        try {   
        	String str = new String(sb);
            File file = new File(filePath);  
            System.out.println(filePath);
            // if file doesnt exists, then create it  
            if (!file.exists()) {  
                file.createNewFile();  
            }  
            FileWriter fw = new FileWriter(file, true);  
            BufferedWriter bw = new BufferedWriter(fw);  
            bw.write(str);  
            bw.flush();  
            bw.close();  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }  
	
	/** 
	 *  从指定路径读取文件，
	 *  然后写入数据库，
	 *  写完后删除文件。
	 * @param filename 目标文件 
	 * @param getFileShellPath 获取远程文件的脚本
	 * @param clearShellPath 清空文件脚本
	 * @throws IOException 
	 */  
	public static void writeMysql(String filename,String tableName) throws IOException {  
		DataCURD dataCURD = new DataCURD();
		dataCURD.initConfig();
		Long startTime = System.currentTimeMillis();
		
		try {  
			String realTableName = null;
			if (tableName.contains(".")) {
				realTableName = tableName.split("\\.")[0];
			} else {
				realTableName = tableName;
			}
            FileInputStream in = new FileInputStream(filename+realTableName+".txt");  
            InputStreamReader inReader = new InputStreamReader(in, "UTF-8");  
            BufferedReader bufReader = new BufferedReader(inReader);  
            String line = null;  
            int i = 1;  
            
            List<Map> lines = new ArrayList<>();
            while((line = bufReader.readLine()) != null){  
            	//将json格式字符串转为map
            	ObjectMapper mapper = new ObjectMapper();  
                Map map = mapper.readValue(line, Map.class);
                lines.add(map);
            }  
            dataCURD.saveForAny(lines, tableName);
            bufReader.close();  
            inReader.close();  
            in.close();  
            Long endTime = System.currentTimeMillis();
            System.out.println("耗时："+(endTime-startTime));
        } catch (Exception e) {  
            e.printStackTrace();  
            System.out.println("读取" + filename + "出错！");  
        }   
	} 
	
	//读取文件
	public void getRemoteFile() {
	    try {  
	      String shpath="/tsgz/getfile.sh";  
	      Process ps = Runtime.getRuntime().exec(shpath);  
	      ps.waitFor();  
	
	      BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));  
	      StringBuffer sb = new StringBuffer();  
	      String line;  
	      while ((line = br.readLine()) != null) {  
	          sb.append(line).append("\n");  
	      }  
	      String result = sb.toString();  
	      System.out.println(result);  
	      }   
	  catch (Exception e) {  
	      e.printStackTrace();  
	      } 
	}
	
	//执行shell脚本
	public static void runShell(String shpath) {
	    try {  
	      Process ps = Runtime.getRuntime().exec(shpath);  
	      ps.waitFor();  
	
	      BufferedReader br = new BufferedReader(new InputStreamReader(ps.getInputStream()));  
	      StringBuffer sb = new StringBuffer();  
	      String line;  
	      while ((line = br.readLine()) != null) {  
	          sb.append(line).append("\n");  
	      }  
	      String result = sb.toString();  
	      System.out.println(result);  
	      }   
	  catch (Exception e) {  
	      e.printStackTrace();  
	      } 
	}

	 /**
     * 删除单个文件
     *
     * @param fileName
     *            要删除的文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String fileName) {
        File file = new File(fileName);
        // 如果文件路径所对应的文件存在，并且是一个文件，则直接删除
        if (file.exists() && file.isFile()) {
            if (file.delete()) {
                System.out.println("删除单个文件" + fileName + "成功！");
                return true;
            } else {
                System.out.println("删除单个文件" + fileName + "失败！");
                return false;
            }
        } else {
            System.out.println("删除单个文件失败：" + fileName + "不存在！");
            return false;
        }
    }
	
  /** 
   *  从最后一行开始读取文件。
   * @param filename 目标文件 
   * @param charset 目标文件的编码格式 
   * @param num 读取行数
   */  
  public static void read(String filename, String charset,int num) {  

      RandomAccessFile rf = null;  
      try {  
          rf = new RandomAccessFile(filename, "r");  
          long len = rf.length();  
          long start = rf.getFilePointer();  
          long nextend = start + len - 1;  
          String line;  
          rf.seek(nextend);  
          int c = -1;  
          int number = 1;
          
          while (nextend > start) {
              if (number<=num) {
                  c = rf.read();  
                  if (c == '\n' || c == '\r' ) {  
                      line = rf.readLine();  
                      if (line != null) {  
                          System.out.println(number+"||"+nextend+":"+new String(line  
                                  .getBytes("ISO-8859-1"), charset));  
                      } else {  
                          System.out.println(line);  
                      }  
                      nextend--; 
                      number++;
                  }  
                  nextend--;  
                  rf.seek(nextend);  
                  if (nextend == 0) {// 当文件指针退至文件开始处，输出第一行  
                      // System.out.println(rf.readLine());  
                      System.out.println(new String(rf.readLine().getBytes(  
                              "ISO-8859-1"), charset));  
                  }  
              }
			}

      } catch (FileNotFoundException e) {  
          e.printStackTrace();  
      } catch (IOException e) {  
          e.printStackTrace();  
      } finally {  
          try {  
              if (rf != null)  
                  rf.close();  
          } catch (IOException e) {  
              e.printStackTrace();  
          }  
      }  
  }
}
